using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net.Http; // 引用：HttpClient 用于调用接口
using System.Net.Http.Headers; // 引用：设置请求头
using Newtonsoft.Json; // 引用：Newtonsoft.Json 用于序列化/反序列化
using Newtonsoft.Json.Serialization; // 引用：驼峰命名等设置
using Mes.Production.Common; // 引用：通用ApiResponse与ApiPaging
using Mes.Production.Models; // 引用：请求与DTO模型
using Mes.Production.Config; // 引用：ApiConfig
using Mes; // 使用 HttpClientHelper

namespace Mes.Production
{
    public partial class ProductionOrderFrm : Form
    {
        // 私有字段：接口基础地址（从配置读取） //
        private readonly string _apiBaseUrl = ApiConfig.GetApiBaseUrl(); // API 基础地址

        // 移除 HttpClient 单例，统一使用 HttpClientHelper

        // 私有字段：分页与筛选状态 //
        private int _pageIndex = 1; // 当前页码，从1开始
        private int _pageSize = 5; // 每页大小
        private int _totalCount = 0; // 总条数

        // 移除内部DTO与分页容器，统一使用 Common 与 Models 下的类型 //

        public ProductionOrderFrm()
        {
            InitializeComponent();
            InitializeUiData(); // 初始化下拉与默认值
            WireEvents(); // 绑定事件
            _ = RefreshListAsync(); // 首次加载列表
        }

        // 初始化控件默认值与下拉数据 //
        private void InitializeUiData()
        {
            // 初始化订单来源下拉（与新增窗体保持一致） //
            var orderSourceItems = new List<KeyValuePair<int?, string>>
            {
                new KeyValuePair<int?, string>(null, "全部"), // 全部选项
                new KeyValuePair<int?, string>(1, "手工录入"), // 1：手工录入
                new KeyValuePair<int?, string>(2, "系统下发"), // 2：系统下发
                new KeyValuePair<int?, string>(3, "APS调度") // 3：APS调度
            };
            this.comboBoxOrderSource.DisplayMember = "Value"; // 下拉显示文本绑定字段
            this.comboBoxOrderSource.ValueMember = "Key"; // 下拉选中值绑定字段
            this.comboBoxOrderSource.DataSource = orderSourceItems; // 绑定数据源

            // 初始化日期控件默认值 //
            this.dateTimePickerStart.Value = new DateTime(DateTime.Today.Year, DateTime.Today.Month, 1); // 设置开始日期为当月第1天
            this.dateTimePickerEnd.Value = DateTime.Today; // 设置结束日期为当前日期

            // 初始化分页控件数值 //
            this.numericUpDownPageIndex.Value = _pageIndex; // 设置页码到控件
            this.numericUpDownPageSize.Value = _pageSize; // 设置每页大小到控件
        }

        // 绑定按钮与分页事件 //
        private void WireEvents()
        {
            this.buttonSearch.Click += async (s, e) =>
            {
                _pageIndex = 1; // 查询时重置页码为1
                this.numericUpDownPageIndex.Value = _pageIndex; // 同步控件
                await RefreshListAsync(); // 刷新列表
            }; // 按钮：查询

            this.buttonReset.Click += async (s, e) =>
            {
                this.textBoxOrderNumber.Text = string.Empty; // 清空订单编号
                this.textBoxFinishedNo.Text = string.Empty; // 清空成品编号
                this.comboBoxOrderSource.SelectedIndex = 0; // 选择“全部”
                this.dateTimePickerStart.Value = new DateTime(DateTime.Today.Year, DateTime.Today.Month, 1); // 重置开始日期为当月第1天
                this.dateTimePickerEnd.Value = DateTime.Today; // 重置结束日期为当前日期
                _pageIndex = 1; // 重置页码
                this.numericUpDownPageIndex.Value = _pageIndex; // 同步控件
                await RefreshListAsync(); // 刷新列表
            }; // 按钮：重置

            this.buttonPrev.Click += async (s, e) =>
            {
                if (_pageIndex > 1) // 如果不是第一页
                {
                    _pageIndex--; // 页码减一
                    this.numericUpDownPageIndex.Value = _pageIndex; // 同步控件
                    await RefreshListAsync(); // 刷新列表
                }
            }; // 按钮：上一页

            this.buttonNext.Click += async (s, e) =>
            {
                var totalPage = (int)Math.Ceiling(_totalCount * 1.0 / Math.Max(1, _pageSize)); // 计算总页数
                if (_pageIndex < totalPage) // 如果不是最后一页
                {
                    _pageIndex++; // 页码加一
                    this.numericUpDownPageIndex.Value = _pageIndex; // 同步控件
                    await RefreshListAsync(); // 刷新列表
                }
            }; // 按钮：下一页

            this.numericUpDownPageIndex.ValueChanged += async (s, e) =>
            {
                _pageIndex = (int)this.numericUpDownPageIndex.Value; // 从控件读取页码
                await RefreshListAsync(); // 刷新列表
            }; // 数值：页码变更

            this.numericUpDownPageSize.ValueChanged += async (s, e) =>
            {
                _pageSize = (int)this.numericUpDownPageSize.Value; // 从控件读取每页大小
                _pageIndex = 1; // 修改每页大小后回到第一页
                this.numericUpDownPageIndex.Value = _pageIndex; // 同步控件
                await RefreshListAsync(); // 刷新列表
            }; // 数值：每页大小变更

            this.buttonAdd.Click += (s, e) =>
            {
                OpenAddProductionOrderDialog(); // 打开新增生产订单对话框
            }; // 按钮：新增
        }

        // 刷新列表主流程 //
        private async Task RefreshListAsync()
        {
            var request = BuildQueryFromUi(); // 根据界面构建请求
            var result = await QueryProductionOrdersAsync(request); // 调用接口获取数据
            if (result != null && result.Data != null) // 判空
            {
                _totalCount = result.Data.TotalCount; // 保存总条数
                this.labelTotal.Text = $"总条数:{_totalCount}"; // 显示总条数
                this.dataGridViewOrders.DataSource = result.Data.PageData; // 绑定数据到表格
                ConfigureGridHeaders(); // 配置表头中文与格式
            }
        }

        // 配置表头中文与格式 //
        private void ConfigureGridHeaders()
        {
            var grid = this.dataGridViewOrders; // 引用表格

            // 隐藏订单Id列，但保留数据值
            if (grid.Columns.Contains("Id"))
            {
                grid.Columns["Id"].Visible = false; // 隐藏Id列
            }

            // 添加序号列（如果不存在）
            if (!grid.Columns.Contains("序号"))
            {
                var indexColumn = new DataGridViewTextBoxColumn();
                indexColumn.Name = "序号";
                indexColumn.HeaderText = "序号";
                indexColumn.Width = 60;
                indexColumn.ReadOnly = true;
                indexColumn.DisplayIndex = 0; // 设置为第一列
                grid.Columns.Insert(0, indexColumn);
            }

            // 合并按钮到同一列：添加/配置“操作”文本列用于自绘两个按钮
            if (!grid.Columns.Contains("操作"))
            {
                var actionColumn = new DataGridViewTextBoxColumn();
                actionColumn.Name = "操作"; // 列名：操作
                actionColumn.HeaderText = "操作"; // 列头：操作
                actionColumn.ReadOnly = true;
                actionColumn.Width = 140; // 适中宽度，容纳两个按钮
                grid.Columns.Add(actionColumn);
            }
            else
            {
                grid.Columns["操作"].Width = 140;
                grid.Columns["操作"].ReadOnly = true;
            }

            // 如存在单独“详情”按钮列则隐藏（使用合并列）
            if (grid.Columns.Contains("详情"))
            {
                grid.Columns["详情"].Visible = false;
            }

            // 绑定自绘与点击命中事件（只绑定一次）
            this.dataGridViewOrders.CellPainting -= DataGridViewOrders_CellPainting;
            this.dataGridViewOrders.CellPainting += DataGridViewOrders_CellPainting;
            this.dataGridViewOrders.CellMouseClick -= DataGridViewOrders_CellMouseClick;
            this.dataGridViewOrders.CellMouseClick += DataGridViewOrders_CellMouseClick;

            // 填充序号列数据
            for (int i = 0; i < grid.Rows.Count; i++)
            {
                if (!grid.Rows[i].IsNewRow)
                {
                    grid.Rows[i].Cells["序号"].Value = i + 1;
                }
            }

            // 设置订单来源列的格式化显示
            if (grid.Columns.Contains("OrderSource"))
            {
                // 为订单来源列添加单元格格式化事件
                grid.CellFormatting -= Grid_CellFormatting; // 先移除可能存在的事件绑定
                grid.CellFormatting += Grid_CellFormatting; // 添加格式化事件
            }

            if (grid.Columns.Contains("OrderNumber")) grid.Columns["OrderNumber"].HeaderText = "订单编号"; // 列头：订单编号
            if (grid.Columns.Contains("OrderSource")) grid.Columns["OrderSource"].HeaderText = "订单来源"; // 列头：订单来源
            if (grid.Columns.Contains("FinishedNo")) grid.Columns["FinishedNo"].HeaderText = "成品编号"; // 列头：成品编号
            if (grid.Columns.Contains("ProducedQuantity")) grid.Columns["ProducedQuantity"].HeaderText = "订单总数量"; // 列头：成品总数量
            if (grid.Columns.Contains("Remarks")) grid.Columns["Remarks"].HeaderText = "备注"; // 列头：备注
            if (grid.Columns.Contains("CreateTime"))
            {
                grid.Columns["CreateTime"].HeaderText = "创建时间"; // 列头：创建时间
                grid.Columns["CreateTime"].DefaultCellStyle.Format = "yyyy-MM-dd"; // 时间格式
            }
        }

        /// <summary>
        /// 处理表格中“删除”按钮点击事件
        /// </summary>
        private async void DataGridViewOrders_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {
            // 行索引小于0表示点击的是表头，直接返回
            if (e.RowIndex < 0) return;

            var grid = sender as DataGridView;
            if (grid == null) return; // 安全校验

            // 仅当点击的是“操作”列或“详情”列时处理
            var colName = grid.Columns[e.ColumnIndex].Name;
            if (colName != "操作" && colName != "详情") return;

            // 读取当前行的主键Id
            var row = grid.Rows[e.RowIndex];
            var idObj = row.Cells["Id"]?.Value;
            if (idObj == null || !int.TryParse(idObj.ToString(), out int id) || id <= 0)
            {
                MessageBox.Show("无法获取选中行的订单Id", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }

            if (colName == "详情")
            {
                try
                {
                    using (var detailFrm = new ProductionDetailFrm(id))
                    {
                        detailFrm.StartPosition = FormStartPosition.CenterParent; // 居中显示
                        detailFrm.ShowDialog(this);
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show($"打开详情失败：{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                return;
            }

            // 二次确认
            var confirm = MessageBox.Show($"确认删除该订单吗？", "确认删除", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
            if (confirm != DialogResult.Yes) return;

            try
            {
                // 组合后端删除接口地址（DELETE）：/api/ProductionOrder/DeleteProductionOrder?id={id}
                var url = $"{_apiBaseUrl}/api/ProductionOrder/DeleteProductionOrder?id={id}";
                var content = await HttpClientHelper.ClientAsync("DELETE", url, false, null);
                var result = JsonConvert.DeserializeObject<ApiResponse<int>>(content);
                var code = result?.Code ?? 500; // 默认失败
                var msg = string.IsNullOrWhiteSpace(result?.Msg) ? result?.Message : result?.Msg; // 兼容 Msg/Message

                if (code == 200)
                {
                    MessageBox.Show("删除成功", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    await RefreshListAsync(); // 刷新列表
                }
                else
                {
                    MessageBox.Show($"删除失败：{msg}", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"删除异常：{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        // 从界面控件构建请求参数 //
        private QueryProductionOrderList BuildQueryFromUi()
        {
            string orderNumber = this.textBoxOrderNumber.Text?.Trim(); // 读取订单编号
            string finishedNo = this.textBoxFinishedNo.Text?.Trim(); // 读取成品编号
            int? orderSource = this.comboBoxOrderSource.SelectedValue as int?; // 读取订单来源（可空）
            string startDate = this.dateTimePickerStart.Value.ToString("yyyy-MM-dd"); // 格式化开始日期
            string endDate = this.dateTimePickerEnd.Value.ToString("yyyy-MM-dd"); // 格式化结束日期

            return new QueryProductionOrderList
            {
                OrderNumber = string.IsNullOrEmpty(orderNumber) ? null : orderNumber, // 若空则置空
                FinishedNo = string.IsNullOrEmpty(finishedNo) ? null : finishedNo, // 若空则置空
                OrderSource = orderSource, // 订单来源
                CreateStartDate = startDate, // 创建开始时间
                CreateEndDate = endDate, // 创建结束时间
                PageIndex = _pageIndex, // 页码
                PageSize = _pageSize // 每页大小
            };
        }

        // 调用接口：查询生产订单列表 //
        private async Task<ApiResponse<Mes.Production.Common.ApiPaging<ProductionOrderListQueryDto>>> QueryProductionOrdersAsync(QueryProductionOrderList request)
        {
            // 生产订单列表接口（GET）：/api/ProductionOrder/GetProductionOrderList //
            //var baseUrl = $"{_apiBaseUrl}/production/api/ProductionOrder/GetProductionOrderList"; // 控制器路由
            var baseUrl = $"{_apiBaseUrl}/api/ProductionOrder/GetProductionOrderList"; // 控制器路由

            // 组装查询字符串，仅包含非空参数 //
            var queryParts = new List<string>(); // 参数片段集合
            if (!string.IsNullOrWhiteSpace(request.OrderNumber)) queryParts.Add($"orderNumber={Uri.EscapeDataString(request.OrderNumber)}"); // 订单编号
            if (!string.IsNullOrWhiteSpace(request.FinishedNo)) queryParts.Add($"finishedNo={Uri.EscapeDataString(request.FinishedNo)}"); // 成品编号
            if (request.OrderSource.HasValue) queryParts.Add($"orderSource={request.OrderSource.Value}"); // 订单来源
            if (!string.IsNullOrWhiteSpace(request.CreateStartDate)) queryParts.Add($"createStartDate={Uri.EscapeDataString(request.CreateStartDate)}"); // 开始日期
            if (!string.IsNullOrWhiteSpace(request.CreateEndDate)) queryParts.Add($"createEndDate={Uri.EscapeDataString(request.CreateEndDate)}"); // 结束日期
            queryParts.Add($"pageIndex={request.PageIndex}"); // 页码
            queryParts.Add($"pageSize={request.PageSize}"); // 每页大小

            var url = queryParts.Count > 0 ? $"{baseUrl}?{string.Join("&", queryParts)}" : baseUrl; // 完整URL

            var respString = await HttpClientHelper.ClientAsync("GET", url, false, null);
            var result = JsonConvert.DeserializeObject<ApiResponse<Mes.Production.Common.ApiPaging<ProductionOrderListQueryDto>>>(respString); // 反序列化响应
            return result; // 返回
        }

        /// <summary>
        /// DataGridView单元格格式化事件处理
        /// </summary>
        private void Grid_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
        {
            var grid = sender as DataGridView;
            if (grid != null && grid.Columns[e.ColumnIndex].Name == "OrderSource" && e.Value != null)
            {
                if (int.TryParse(e.Value.ToString(), out int sourceId))
                {
                    e.Value = GetOrderSourceText(sourceId);
                    e.FormattingApplied = true;
                }
            }
        }

        /// <summary>
        /// 根据订单来源ID获取对应的文本显示
        /// </summary>
        /// <param name="sourceId">订单来源ID</param>
        /// <returns>对应的文本</returns>
        private string GetOrderSourceText(int sourceId)
        {
            switch (sourceId)
            {
                case 1:
                    return "手工录入";
                case 2:
                    return "系统下发";
                case 3:
                    return "APS调度";
                default:
                    return "未知";
            }
        }

        /// <summary>
        /// 打开新增生产订单对话框
        /// </summary>
        private void OpenAddProductionOrderDialog()
        {
            try
            {
                using (var addForm = new AddProductionOrder())
                {
                    // 以对话框形式打开新增窗体
                    var result = addForm.ShowDialog(this);

                    // 如果用户点击了确定并成功保存，则刷新列表
                    if (result == DialogResult.OK)
                    {
                        _ = RefreshListAsync(); // 刷新列表数据
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"打开新增窗体失败：{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        // 自绘两个适中大小按钮（详情/删除）
        private void DataGridViewOrders_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
        {
            if (e.RowIndex < 0 || e.ColumnIndex < 0) return; // 头部不处理
            var grid = sender as DataGridView;
            if (grid == null) return;
            if (e.ColumnIndex >= grid.Columns.Count) return;
            if (grid.Columns[e.ColumnIndex].Name != "操作") return;

            e.Handled = true;
            e.PaintBackground(e.CellBounds, true);

            // 适中按钮尺寸：高度为行高的 60%，固定宽58，左右内边距6
            int padding = 6;
            int btnHeight = Math.Max(20, (int)(e.CellBounds.Height * 0.6));
            int btnWidth = 58;
            int centerY = e.CellBounds.Top + (e.CellBounds.Height - btnHeight) / 2;

            var rectDetail = new Rectangle(e.CellBounds.Left + padding, centerY, btnWidth, btnHeight);
            var rectDelete = new Rectangle(rectDetail.Right + padding, centerY, btnWidth, btnHeight);

            // 将按钮矩形缓存到 Tag（绝对坐标）供点击命中
            if (this.dataGridViewOrders.Tag == null)
            {
                this.dataGridViewOrders.Tag = new Dictionary<string, Rectangle>();
            }
            var dict = this.dataGridViewOrders.Tag as Dictionary<string, Rectangle>;
            dict[$"btn_detail_{e.RowIndex}"] = rectDetail;
            dict[$"btn_delete_{e.RowIndex}"] = rectDelete;

            using (var brushDetail = new SolidBrush(Color.FromArgb(52, 152, 219))) // 蓝色
            using (var brushDelete = new SolidBrush(Color.FromArgb(231, 76, 60))) // 红色
            using (var brushText = new SolidBrush(Color.White))
            {
                // 圆角矩形
                FillRoundedRectangle(e.Graphics, brushDetail, rectDetail, 4);
                FillRoundedRectangle(e.Graphics, brushDelete, rectDelete, 4);

                var sf = new StringFormat { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center };
                e.Graphics.DrawString("详情", this.dataGridViewOrders.Font, brushText, rectDetail, sf);
                e.Graphics.DrawString("删除", this.dataGridViewOrders.Font, brushText, rectDelete, sf);
            }
        }

        // 点击命中处理
        private async void DataGridViewOrders_CellMouseClick(object sender, DataGridViewCellMouseEventArgs e)
        {
            if (e.RowIndex < 0 || e.ColumnIndex < 0) return;
            var grid = sender as DataGridView;
            if (grid == null) return;
            if (e.ColumnIndex >= grid.Columns.Count) return;
            if (grid.Columns[e.ColumnIndex].Name != "操作") return;

            // 读取当前行主键
            var row = grid.Rows[e.RowIndex];
            var idObj = row.Cells["Id"]?.Value;
            if (idObj == null || !int.TryParse(idObj.ToString(), out int id) || id <= 0)
            {
                MessageBox.Show("无法获取选中行的订单Id", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }

            // 命中测试（转换点击点为绝对坐标，与缓存一致）
            var cellRect = grid.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, false);
            var clickPoint = new Point(cellRect.Left + e.X, cellRect.Top + e.Y);

            var dict = grid.Tag as Dictionary<string, Rectangle>;
            if (dict == null) return;
            dict.TryGetValue($"btn_detail_{e.RowIndex}", out var rectDetail);
            dict.TryGetValue($"btn_delete_{e.RowIndex}", out var rectDelete);

            if (rectDetail.Contains(clickPoint))
            {
                try
                {
                    using (var detailFrm = new ProductionDetailFrm(id))
                    {
                        detailFrm.StartPosition = FormStartPosition.CenterParent;
                        detailFrm.ShowDialog(this);
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show($"打开详情失败：{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                return;
            }

            if (rectDelete.Contains(clickPoint))
            {
                var confirm = MessageBox.Show($"确认删除该订单吗？", "确认删除", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
                if (confirm != DialogResult.Yes) return;

                try
                {
                    var url = $"{_apiBaseUrl}/api/ProductionOrder/DeleteProductionOrder?id={id}";
                    var content = await HttpClientHelper.ClientAsync("DELETE", url, false, null);
                    var result = JsonConvert.DeserializeObject<ApiResponse<int>>(content);
                    var code = result?.Code ?? 500;
                    var msg = string.IsNullOrWhiteSpace(result?.Msg) ? result?.Message : result?.Msg;
                    if (code == 200)
                    {
                        MessageBox.Show("删除成功", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                        await RefreshListAsync();
                    }
                    else
                    {
                        MessageBox.Show($"删除失败：{msg}", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show($"删除异常：{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }

        // 简易圆角矩形绘制（避免扩展方法在此项目版本下不兼容）
        private void FillRoundedRectangle(Graphics g, Brush brush, Rectangle bounds, int radius)
        {
            using (var path = new System.Drawing.Drawing2D.GraphicsPath())
            {
                int d = radius * 2;
                path.AddArc(bounds.Left, bounds.Top, d, d, 180, 90);
                path.AddArc(bounds.Right - d, bounds.Top, d, d, 270, 90);
                path.AddArc(bounds.Right - d, bounds.Bottom - d, d, d, 0, 90);
                path.AddArc(bounds.Left, bounds.Bottom - d, d, d, 90, 90);
                path.CloseFigure();
                var old = g.SmoothingMode;
                g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
                g.FillPath(brush, path);
                g.SmoothingMode = old;
            }
        }
    }
}
